package model.components.networks.sdn;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import model.components.links.comparator.LinkNumberComparator;
import model.components.links.link.Link;
import model.components.links.link.SdnLink;
import model.components.networks.Network;
import model.components.networks.NetworkGraph;
import model.components.nodes.comparator.NodeNumberComparator;
import model.components.nodes.node.Node;
import model.components.nodes.node.sdn.SdnNode;
import edu.uci.ics.jung.graph.Graph;

public class SdnNetwork extends Network
{	
	private int cpuPrice;
	public int getCPUprice(){ return cpuPrice; }
	public void setCPUprice( int cpuPrice ){ this.cpuPrice = cpuPrice; }
	
	private int ramPrice;
	public int getRAMprice(){ return ramPrice; }
	public void setRAMprice( int ramPrice ){ this.ramPrice = ramPrice; }
	
	private int storagePrice;
	public int getStoragePrice(){ return storagePrice; }
	public void setStoragePrice( int storagePrice ){ this.storagePrice = storagePrice; }

	private int bwPrice;
	public int getBWprice(){ return bwPrice; }
	public void setBWprice( int bwPrice ){ this.bwPrice = bwPrice; }

	private int networkRevenue;
	public int getNetworkRevenue(){ return networkRevenue; }
	public void setNetworkRevenue( int networkRevenue ){ this.networkRevenue = networkRevenue; }
	
	private boolean selected = false;
	public boolean isSelected(){ return selected; }
	public void setSelected( boolean selected ){ this.selected = selected; }
	
	public SdnNetwork( String namePrefix )
	{
		super( namePrefix, 0, new NetworkGraph() );
	}
	
	public SdnNetwork( String namePrefix, int number, Graph< Node, Link > graph, int cpuPrice, int ramPrice, int storagePrice, int bwPrice ) 
	{
    	super( namePrefix, number, graph );
    	
    	this.setCPUprice( cpuPrice );
    	this.setRAMprice( ramPrice );
    	this.setStoragePrice( storagePrice );
    	this.setBWprice( bwPrice );
    }
	
	public SdnNetwork getCopy()
    {
		SdnNetwork sdnNetwork = new SdnNetwork( this.getNamePrefix(), this.getNumber(), ( (NetworkGraph) this.getGraph() ).getCopy(), this.getCPUprice(), this.getRAMprice(), this.getStoragePrice(), this.getBWprice() );
		sdnNetwork.setState( this.getState() );
    	sdnNetwork.setChange( this.isChange() );
    	sdnNetwork.setTimeStamp( this.getTimeStamp() );
    	
    	return sdnNetwork;
    }
	
	public List< SdnNode > getSdnNodes()
	{
		List< SdnNode > sdnNodes = new ArrayList< SdnNode >();
		
		for( Node node: this.getNodes() )
			sdnNodes.add( (SdnNode) node );
		
		Collections.sort( sdnNodes, new NodeNumberComparator() );
		
		return sdnNodes;
	}
	
	public double[][] getSdnNodesAvailableCapacities()
	{
		double sdnNodesAvailableCapacities[][] = new double[ 3 ][ this.getSdnNodes().size() ];
		
		for( int i = 0; i < this.getNodes().size(); i++ )
		{  
			SdnNode sdnNode = this.getSdnNodes().get( i );
			
			sdnNodesAvailableCapacities[ 0 ][ i ] = sdnNode.getAvailableCPU();
			sdnNodesAvailableCapacities[ 1 ][ i ] = sdnNode.getAvailableRAM();
			
			if( sdnNode.getType().equals( Node.SERVER_TYPE ) )
				sdnNodesAvailableCapacities[ 2 ][ i ] = sdnNode.getAvailableStorage();
		}
		
		return sdnNodesAvailableCapacities;
	}
		
    public List< SdnLink > getSdnLinks()
    {
    	List< SdnLink > sdnLink = new ArrayList< SdnLink >();
		
		for( Link link: this.getLinks() )
			sdnLink.add( (SdnLink) link );
		
		Collections.sort( sdnLink, new LinkNumberComparator() );
    	
    	return sdnLink;
	}
    
	public double[][] getAvailableBWs()
	{
		double sdnLinksAvailableBWs[][] = new double[ this.getNodes().size() ][ this.getNodes().size() ];
		
		for( SdnLink sdnLink: this.getSdnLinks() )
		{
			sdnLinksAvailableBWs[ sdnLink.getFirstNode().getNumber()  ][ sdnLink.getSecondNode().getNumber() ] = sdnLink.getAvailableBW();
			sdnLinksAvailableBWs[ sdnLink.getSecondNode().getNumber() ][ sdnLink.getFirstNode().getNumber()  ] = sdnLink.getAvailableBW();
		}
		
		return sdnLinksAvailableBWs;
	}
	
}
